#include "Wt.h"

char *WtToString(Tcl_Obj *obj)
{
  return obj ? Tcl_GetStringFromObj(obj, NULL) : "";
}

Tcl_Obj *WtNewString(const char *val)
{
  return Tcl_NewStringObj(val ? val : NULL, val ? -1 : 0);
}

Tcl_Obj *WtNewBool(int val)
{
  return Tcl_NewBooleanObj(val);
}

int WtGetListSize(Tcl_Obj *list)
{
  int len;
  ap_assert(Tcl_ListObjLength(NULL, list, &len) == TCL_OK);
  return len;
}

Tcl_Obj *WtGetFirstListElement(Tcl_Obj *list)
{
  Tcl_Obj *obj;
  ap_assert(Tcl_ListObjIndex(NULL, list, 0, &obj) == TCL_OK);
  return obj;
}

void WtAppendToList(Tcl_Obj *list, Tcl_Obj *val)
{
  ap_assert(Tcl_ListObjAppendElement(NULL, list, val) == TCL_OK);
}

void WtAppendListToList(Tcl_Obj *target, Tcl_Obj *list)
{
  ap_assert(Tcl_ListObjAppendList(NULL, target, list) == TCL_OK);
}

Tcl_Obj *WtGetListItem(Tcl_Obj *list, int i)
{
  Tcl_Obj *obj;
  ap_assert(Tcl_ListObjIndex(NULL, list, i, &obj) == TCL_OK);
  return obj;
}

void WtReplaceInList(Tcl_Obj *list, int start, int count, int objc, Tcl_Obj *const objv[])
{
  if (Tcl_ListObjReplace(NULL, list, start, count, objc, objv) != TCL_OK) {
    ap_assert(0);
  }
}

void WtApLog(const char *file, int line, int level, WtContext *w, const char *fmt, ...)
{
  char buf [MAX_STRING_LEN];
  va_list args;

  va_start(args, fmt);

  if (ap_vsnprintf(buf, sizeof(buf), fmt, args)) {
    if (w->active->request.apReq) {
      ap_log_rerror(file, line, level, w->active->request.apReq, "%s", buf);
    } else {
      ap_log_error(file, line, level, w->apServer, "%s", buf);
    }
  }

  va_end(args);
}

char *WtSafeStr(const char *str)
{
  return str ? (char *)str : "";
}

void WtPrintTclError(WtContext *w, Tcl_Interp *interp)
{
  Tcl_Obj *err;
  char *bytes;
  int len;

  err = Tcl_NewStringObj(NULL, 0);
  Tcl_IncrRefCount(err);

  Tcl_AppendToObj(err, "<html>\n<head>\n<title>Wtcl Error</title>\n</head>\n<body>\n", -1);
  Tcl_AppendToObj(err, "<h1>Error</h1>\n", -1);
  Tcl_AppendToObj(err, "<p>An error occurred while processing this request:</p>\n", -1);
  Tcl_AppendToObj(err, "<p><ul><pre>\n", -1);
  Tcl_AppendObjToObj(err, Tcl_GetObjResult(interp));
  Tcl_AppendToObj(err, "</pre></ul></p>\n", -1);
  Tcl_AppendToObj(err, "</body>\n</html>\n", -1);

  bytes = Tcl_GetStringFromObj(err, &len);

  if (len) {
    ap_rwrite(bytes, len, w->active->request.apReq);
  }

  Tcl_DecrRefCount(err);
}
